﻿#define _CRT_SECURE_NO_WARNINGS 1

#include<iostream>
#include<stdlib.h>
#include<assert.h>
#include<vector>
#include<string>
using namespace std;

//int main()
//{
//	int a = 0;
//	int& b = a; //引用
//
//	cout << &a << endl;
//	cout << &b << endl;
//
//	return 0;
//}
//


//typedef struct ListNode
//{
//	int val;
//	struct ListNode* next;
//}ListNode,*PListNode;


//cpp引用的玩法
//void PushBack(ListNode*& phead, int x)
////void PushBack(PListNode& phead, int x)
//{
//	ListNode* newnode = (ListNode*)malloc(sizeof(ListNode));
//	//...
//	if (phead == NULL)
//	{
//		phead = newnode;
//	}
//	else
//	{
//
//	}
//}
//
//int main()
//{
//	ListNode* plist = NULL;
//	PushBack(plist, 1);
//	PushBack(plist, 2);
//	PushBack(plist, 3);
//	PushBack(plist, 4);
//
//	return 0;
//}


//1.引用必须在定义的地方初始化
//2. 一个变量可以有多个引用
//3. 引用一旦引用一个实体，再不能引用其他实体

//void TestRef()
//{
//	int a = 10;
//	// int& ra;  // 该条语句编译时会出错
//	int& ra = a; // ra是a的引用
//	int& rra = a; // rra是a的引用
//	int& rrra = ra; // rrra是ra的引用
//	
//	cout << a << "  " << &a << endl;
//	cout << ra << "  " << &ra << endl; 
//	cout << rra << "  " << &rra << endl;
//	cout << rrra << "  " << &rrra << endl;
//}
//
//int main()
//{
//	TestRef();
//
//	return 0;
//}


//void TestRef()
//{
//	int a = 10;
//	int b = 20;
//
//	int& x = a; 
//	int& x = b; 
//	
//	cout << a << "  " << &a << endl;
//	cout << x << "  " << &x << endl; 
//	cout << b << "  " << &b << endl;
//	cout << x << "  " << &x << endl;
//}
//
//int main()
//{
//	TestRef();
//
//	return 0;
//}

//void TestConstRef()
//{
//	const int a = 10;
//	//int& ra = a;  // 该语句编译时会出错，a为常量
//	const int& ra = a;
//
//	// int& b = 10; // 该语句编译时会出错，b为常量
//	const int& b = 10;
//
//	double d = 12.34;
//	//int& rd = d; // 该语句编译时会出错，类型不同
//	const int& rd = d;
//}
//



//引用做返回值

//传值返回    
//int Count()
//{
//	int n = 0;
//	n++;
//	// ...
//	return n;
//}
//
//int main()
//{
//	int ret = Count();
//	cout << ret << endl;
//
//	return 0;
//}


//void Swap(int& left, int& right)
//{
//	int temp = left;
//	left = right;
//	right = temp;
//}
//
//int main()
//{
//	int a = 10;
//	int b = 20;
//
//	Swap(a, b);
//	cout << "a = " << a << endl;
//	cout << "b = " << b << endl;
//
//	return 0;
//}

//传引用返回
//int& Count()
//{
//	int n = 0;
//	n++;
//	// ...
//	return n;
//}
//
//int main()
//{
//	int ret = Count();
//	//这里打印的结果可能是1，也可能是随机值
//	cout << ret << endl;
//
//	return 0;
//}


//int& Count()
//{
//	int n = 0;
//	n++;
//	// ...
//	return n;
//}
//
//int main()
//{
//	int& ret = Count();
//	//这里打印的结果可能是1，也可能是随机值
//	cout << ret << endl;
//	cout << ret << endl; //被覆盖
//
//	return 0;
//}



//int& Add(int a, int b)
//{
//	int c = a + b;
//	return c;
//}
//
//int main()
//{
//	int& ret = Add(1, 2);
//	Add(3, 4);
//	cout << "Add(1, 2) is :" << ret << endl;
//	return 0;
//}
//注意：如果函数返回时，出了函数作用域，如果返回对象还在(还没还给系统)，则可以使用
//引用返回，如果已经还给系统了，则必须使用传值返回。


//#include <time.h>
//struct A { int a[10000]; };
//void TestFunc1(A a) {}
//void TestFunc2(A& a) {}
//void TestRefAndValue()
//{
//	A a;
//	// 以值作为函数参数
//	size_t begin1 = clock();
//	for (size_t i = 0; i < 10000; ++i)
//		TestFunc1(a);
//	size_t end1 = clock();
//	// 以引用作为函数参数
//	size_t begin2 = clock();
//	for (size_t i = 0; i < 10000; ++i)
//		TestFunc2(a);
//	size_t end2 = clock();
//	// 分别计算两个函数运行结束后的时间
//	cout << "TestFunc1(A)-time:" << end1 - begin1 << endl;
//	cout << "TestFunc2(A&)-time:" << end2 - begin2 << endl;
//}
//
//int main()
//{
//	TestRefAndValue();
//
//	return 0;
//}


//#include <time.h>
//struct A { int a[10000]; };
//A a;
//// 值返回
//A TestFunc1() { return a; }
//// 引用返回
//A& TestFunc2() { return a; }
//void TestReturnByRefOrValue()
//{
//	// 以值作为函数的返回值类型
//	size_t begin1 = clock();
//	for (size_t i = 0; i < 100000; ++i)
//		TestFunc1();
//	size_t end1 = clock();
//	// 以引用作为函数的返回值类型
//	size_t begin2 = clock();
//	for (size_t i = 0; i < 100000; ++i)
//		TestFunc2();
//	size_t end2 = clock();
//	// 计算两个函数运算完成之后的时间
//	cout << "TestFunc1 time:" << end1 - begin1 << endl;
//	cout << "TestFunc2 time:" << end2 - begin2 << endl;
//}
//
//int main()
//{
//	TestReturnByRefOrValue();
//	
//	return 0;
//}

//传引用传参（任何时候都可以）
//1、提高效率
//2、输出型参数（形参的修改，影响实参）

//传引用返回（出了函数作用域对象还在才可以用）
//1、提高效率
//2、修改返回对象

struct SeqList
{
	int* a;
	int size;
	int capacity;
};



//读取第i个位置的值
//修改第i个位置的值
//C的接口设计

//读取第i个位置的值
//int SLAT(struct SeqList* ps, int i)
//{
//	assert(i < ps->size);
//	//...
//	return ps->a[i];
//}
////修改第i个位置的值
//void SLModify(struct SeqList* ps, int i, int x)
//{
//	assert(i < ps->size);
//
//	//...
//	ps->a[i] = x;
//}


//CPP的接口设计

//读 or 修改第i个位置的值
//int& SLAT(struct SeqList& ps, int i)
//{
//	assert(i < ps.size);
//	//...
//	return ps.a[i];
//}
//
//int main()
//{
//	struct SeqList s;
//	//...
//	SLAT(s, 0) = 10;
//	SLAT(s, 1) = 20;
//	SLAT(s, 2) = 30;
//	cout << SLAT(s, 0) << endl;
//	cout << SLAT(s, 1) << endl;
//	cout << SLAT(s, 2) << endl;
//
//	return 0;
//}



////升级成了类
//#define N 10
//struct SeqList
//{
//	//成员函数
//	int& at(int i)
//	{
//		assert(i < N);
//		return a[i];
//	}
//	//成员变量
//	int a[N];
//};
//
//int main()
//{
//	struct SeqList s1;//兼容c的用法
//	SeqList s2;//c++更喜欢这样定义
//
//	for (size_t i = 0; i < N; i++)
//	{
//		s2.at(i) = i;
//	}
//	for (size_t i = 0; i < N; i++)
//	{
//		cout << s2.at(i) << " ";
//	}
//	cout << endl;
//
//	return 0;
//}



//在引用的过程中
//权限可以平移
//权限可以缩小
//权限不能放大

//int main()
//{
//	//a是鲁智深 可以喝酒 可以吃肉 不能杀人
//	//给a取个别名b 叫花和尚 可以喝酒 可以吃肉 可以杀人？
//	
//	//权限的放大
//	const int a = 0;
//	int& b = a;
//
//	return 0;
//}

//int main()
//{
//	//权限的平移
//	const int a = 0;
//	const int& b = a;
//
//	return 0;
//}


//int main()
//{
//	//权限的缩小
//	int a = 0; //a可以修改，可以影响b
//	const int& b = a;
//
//	return 0;
//}

//int main()
//{
//	int i = 0;
//	//double& d = i;//临时变量具有常性
//	const double& d = i;
//
//	return 0;
//}



//引用和指针底层是一样的
//int main()
//{
//	int a = 0;
//	int* p1 = &a;
//	int& ref = a;
//	
//	return 0;
//}

//引用就是化了妆的指针


//内联函数

//#define N 10
////实现一个ADD的宏函数
//
//#define ADD(x, y) ((x)+(y))
//int main()
//{
//	ADD(1, 2);
//	cout << ADD(1, 2) << endl;
//
//	return 0;
//}
//
////宏的缺点：
////1、容易出错，语法坑很多
////2、不能调试
////3、没有类型安全检查
//
////宏函数的优点：
////1、没有类型的严格限制
////2、针对频繁调用小函数，不需要再建立栈帧，提高了效率
//
//
////内联函数
////优点：不会建立栈帧
//inline int add(int x, int y)
//{
//	return x + y;
//}
////不调用函数，直接展开
//int main()
//{
//	int ret = add(1, 2);
//	cout << ret << endl;
//
//	return 0;
//}

//#include"Func.h"
//
//int main()
//{
//	func(10);
//	return 0;
//}



//auto关键字 --- 自动推导
//int main()
//{
//	int a = 0;
//	auto b = a;
//	auto c = &a;
//	auto& d = a;
//
//	//普通场景没有什么价值
//	//类型很长，就有价值,简化代码
//	std::vector<std::string> v;
//	//std::vector<std::string>::iterator it = v.begin();;
//	auto it = v.begin();
//
//	return 0;
//}


//typeid --- 看实际类型
//int main()
//{
//	int a = 0;
//	auto b = a;
//	auto c = &a;
//	auto& d = a;
//
//	cout << typeid(b).name() << endl;
//	cout << typeid(c).name() << endl;
//	cout << typeid(d).name() << endl;
//
//	return 0;
//}



//范围for
//int main()
//{	
//	int array[] = { 1, 2, 3, 4, 5 };
//
//	for (int i = 0; i < sizeof(array) / sizeof(array[0]); ++i)
//	{
//		array[i] *= 2;
//	}
//		
//
//	for (int i = 0; i < sizeof(array) / sizeof(array[0]); ++i)
//	{
//		cout << array[i] << " ";
//	}
//	cout << endl;
//
//	//范围for
//	//依次取数组中的数据赋值给e
//	//自动判断结束
//	//自动迭代
//	for (auto e : array)
//	{
//		cout << e << " ";
//	}
//	cout << endl;
//
//	return 0;
//}


//int main()
//{
//	int array[] = { 1,2,3,4,5 };
//
//	for (auto& x : array)
//	{
//		x *= 2;
//	}
//
//	for (auto x : array)
//	{
//		cout << x << " ";
//	}
//	cout << endl;
//
//	return 0;
//}



//nullptr关键字
//C的一个坑
//void func(int)
//{
//	cout << "f(int)" << endl;
//}
//void func(int*)
//{
//	cout << "f(int*)" << endl;
//}
//int main()
//{
//	func(0);
//	func(NULL);
//
//	func((int*)NULL);
//	func(nullptr);//nullptr --- (void*)类型
//
//	return 0;
//}



//C++兼容C语言，结构用法可以继续使用
//同时struct也升级成了类
//struct Stack
//{
//	//成员函数	
//	void Init()
//	{
//		a = nullptr;
//		top = capacity = 0;
//	}
//
//	//成员变量
//	int* a;
//	int top;
//	int capacity;
//};
//
//void StackInit(struct Stack* ps)
//{
//	//...
//}
//
//int main()
//{
//	struct Stack st1;
//	StackInit(&st1);
//
//	Stack st2;
//	st2.Init();
//
//	return 0;
//}



////实例化
//class Date
//{
//public:
//	void Init(int year, int month, int day)
//	{
//		_year = year;
//		_month = month;
//		_day = day;
//	}
//private:
//	int _year;  //声明
//	int _month;
//	int _day;
//};
//
//int main()
//{
//	//Date::_year; 
//	//Date._year; //不能访问：声明没开空间
//
//	//定义 开空间
//	Date d1;
//	d1.Init(2023, 7, 29);
//
//	Date d2;
//	d2.Init(2023, 7, 29);
//
//	cout << sizeof(Date) << endl;
//	cout << sizeof(d1) << endl;
//
//	return 0;
//}
//	